package isjinhao.jlox;


import isjinhao.jlox.grammar.code.CodeParser;
import isjinhao.jlox.lexical.LoxScanner;
import isjinhao.jlox.lexical.Token;
import isjinhao.jlox.lexical.TokenType;
import isjinhao.jlox.run.Interpreter;
import isjinhao.jlox.run.RuntimeError;

import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Paths;

/***
 * @Author ISJINHAO
 * @Date 2021/2/23 16:34
 */
public class Lox {

    private static final Interpreter INTERPRETER = new Interpreter();

    static boolean hadError = false;
    static boolean hadRuntimeError = false;

    public static void main(String[] args) throws IOException {
        if (args.length == 1) {
            runFile(args[0]);
        } else {
            System.out.println("Lox: only one file is needed!");
            System.exit(64);
        }
    }

    private static void runFile(String path) throws IOException {
        byte[] bytes = Files.readAllBytes(Paths.get(path));
        run(new String(bytes, Charset.defaultCharset()));
        // Indicate an error in the exit code.
        if (hadError) {
            System.exit(65);
        }
        if (hadRuntimeError) {
            System.exit(70);
        }
    }

    public static void run(String source) {
        LoxScanner loxScanner = new LoxScanner(source);
        CodeParser codeParser = new CodeParser(loxScanner.scanTokens());
//        List<Statement> statements = codeParser.parse();

        // Stop if there was a syntax error.
        if (hadError) {
            return;
        }
//        INTERPRETER.interpret(statements);
    }

    public static void error(int line, String message) {
        report(line, "", message);
    }

    public static void error(Token token, String message) {
        if (token.getType() == TokenType.EOF) {
            report(token.getLine(), " at end", message);
        } else {
            report(token.getLine(), " at '" + token.getLexeme() + "'", message);
        }
    }

    public static void runtimeError(RuntimeError error) {
        System.err.println(error.getMessage() + "[line " + error.getToken().getLine() + "]");
        hadRuntimeError = true;
    }

    private static void report(int line, String where, String message) {
        System.err.println("[line " + line + "] Error" + where + ": " + message);
        hadError = true;
    }

}